#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <linux/can.h>

#define SERIAL_PORT "/dev/ttyCH341USB0"  // 替换为实际的 tty 设备
#define BAUD_RATE B9600

int configure_serial_port(int fd) {
    struct termios options;

    // 获取串口当前配置
    if (tcgetattr(fd, &options) < 0) {
        perror("tcgetattr");
        return -1;
    }

    // 设置波特率
    cfsetispeed(&options, BAUD_RATE);
    cfsetospeed(&options, BAUD_RATE);

    // 设置 8N1 模式
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;

    // 设置为原始模式（不处理特殊字符）
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    options.c_iflag &= ~(IXON | IXOFF | IXANY);
    options.c_oflag &= ~OPOST;

    // 将配置写入串口
    if (tcsetattr(fd, TCSANOW, &options) < 0) {
        perror("tcsetattr");
        return -1;
    }

    return 0;
}

void send_can_data(int serial_fd, char *frame_buf, size_t data_length)
{
	int ret;
	if (data_length>8 || data_length<=0) {
		perror("data length");
	}
	ret = write(serial_fd, frame_buf, data_length);
	if (ret < 0) {
        perror("write");
    }
}

void recv_can_data(int serial_fd, char *frame_buf, size_t data_length)
{
	int ret;
	if (data_length>8 || data_length<=0) {
		perror("data length");
	}
	ret = read(serial_fd, frame_buf, data_length);
	if (ret < 0) {
        perror("read");
    }	
}

int main() {
    int serial_fd;
    char buf[8] = {0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88};
    ssize_t n;
	ssize_t data_length = 8;

    // 打开串口
    serial_fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_SYNC);
    if (serial_fd < 0) {
        perror("open serial port");
        return 1;
    }

    // 配置串口
    if (configure_serial_port(serial_fd) < 0) {
        close(serial_fd);
        return 1;
    }
	
	// 假设接收到的数据为标准的 CAN 帧格式
	struct can_frame frame;

    while (1) {
		 // 从串口发送can数据
		memcpy(frame.data, buf, data_length);
		send_can_data(serial_fd, frame.data, data_length);
		for (int i = 0; i < data_length; i++) {
			printf("%02X ", frame.data[i]);
        }
		printf("\tSend CAN frame data\n");
		
        // 从串口读取can数据
		recv_can_data(serial_fd, frame.data, data_length);
		for (int i = 0; i < data_length; i++) {
			printf("%02X ", frame.data[i]);
        }
		printf("\tReceived CAN frame data\n");
    }

    close(serial_fd);
    return 0;
}

//编译方式：gcc tty_to_can.c -o tty_to_can